Skip to content

Conversation

rhenium
Copy link
Member

@rhenium rhenium commented Aug 12, 2025

This PR fixes two issues shown in #927, which affects OpenSSL 3.0 or later.


pkey: add more tests for OpenSSL::PKey.read

Add tests covering edge cases in the current behavior to prevent accidental regressions. The next patches will update the OpenSSL 3.x path.


pkey: pass pem_password_cb to OSSL_DECODER only when it is needed

Specify OSSL_DECODER_CTX_set_pem_password_cb() only when we expect a passphrase-protected private key.

OSSL_DECODER appears to try to decrypt every PEM block in the input even when the PEM header does not match the requested selection. This can cause repeated prompts for a passphrase in a single OpenSSL::PKey.read call.


pkey: stop retrying after non-retryable error from OSSL_DECODER

Continue processing only when OSSL_DECODER_from_bio() returns the error code ERR_R_UNSUPPORTED. Otherwise, raise an exception without retrying decoding the input in another format.

This fixes another case where OpenSSL::PKey.read prompts for a passphrase multiple times when the input contains more than one passphrase-protected PEM blocks and the first one cannot be decoded.

I am not entirely sure if error code ERR_R_UNSUPPORTED is considered part of the public interface of OpenSSL, but this seems to be the only option available and is the approach used internally by the PEM_read_bio_*() functions.


Fixes #927

Add tests covering edge cases in the current behavior to prevent
accidental regressions. The next patches will update the OpenSSL 3.x
path.
Specify OSSL_DECODER_CTX_set_pem_password_cb() only when we expect a
passphrase-protected private key.

OSSL_DECODER appears to try to decrypt every PEM block in the input even
when the PEM header does not match the requested selection. This can
cause repeated prompts for a passphrase in a single OpenSSL::PKey.read
call.
Continue processing only when OSSL_DECODER_from_bio() returns the error
code ERR_R_UNSUPPORTED. Otherwise, raise an exception without retrying
decoding the input in another format.

This fixes another case where OpenSSL::PKey.read prompts for a
passphrase multiple times when the input contains multiple
passphrase-protected PEM blocks and the first one cannot be decoded.

I am not entirely sure if the error code ERR_R_UNSUPPORTED is considered
part of the public interface of OpenSSL, but this seems to be the only
option available and is the approach used internally by the
PEM_read_bio_*() functions.

Fixes ruby#927
@rhenium rhenium force-pushed the ky/pkey-read-fix-repeated-prompts branch from ff363eb to 63d3c2e Compare September 2, 2025 19:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Enter PEM pass phrase does not work correctly
1 participant